package com.woniu.exception;

import com.woniu.common.ResponseInfo;
import com.woniu.enums.ServiceExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 全局异常处理
 */
@ConditionalOnMissingClass("org.springframework.cloud.gateway.config.GatewayAutoConfiguration")
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理参数校验 MethodArgumentNotValidException 异常
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseInfo exceptionHandler2(MethodArgumentNotValidException e) {
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        String message = allErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";"));
        return ResponseInfo.fail(message);
    }

    /**
     * 处理BindException 参数校验
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public ResponseInfo<String> exceptionHandler2(BindException e) {
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        String message = allErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";"));
        return ResponseInfo.fail(message);
    }

    /**
     * 处理 DuplicateKeyException 异常
     */
    @ExceptionHandler(DuplicateKeyException.class)
    @ResponseBody
    public ResponseInfo DuplicateKeyExceptionHandler(
            DuplicateKeyException e
    ) {
        log.debug("[DuplicateKeyExceptionHandler]", e);
        e.printStackTrace();
        Throwable cause = e.getCause();
        if(cause instanceof java.sql.SQLIntegrityConstraintViolationException){
            return ResponseInfo.fail(ServiceExceptionEnum.DATA_REPEAT_ERROR);
        }
        return ResponseInfo.fail(e.getMessage());
    }

    /**
     * 处理其它 Exception 异常
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseInfo exceptionHandler(
            Exception ex
    ) {
        log.debug("[exceptionHandler]", ex);
        ex.printStackTrace();
        //return ResponseInfo.fail(ex.getMessage());
        return ResponseInfo.fail("哎哟，有延迟，请稍等一会");
    }

    /**
     * 处理 ServiceException 异常
     */
    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public ResponseInfo serviceExceptionHandler(
            ServiceException ex
    ) {
        log.debug("[serviceExceptionHandler]", ex);
        ex.printStackTrace();
        return ResponseInfo.fail(ex.getCode(), ex.getMessage());
    }

    /**
     * 处理 MyErrorException 异常
     */
    @ExceptionHandler(MyErrorException.class)
    @ResponseBody
    public ResponseInfo myErrorExceptionHandler(
             MyErrorException ex
    ) {
        //log.debug("[serviceExceptionHandler]", ex);
        ex.printStackTrace();
        return ResponseInfo.fail(ex.getMessage());
    }


}
